/**
 * 流式TTS代理客户端
 * 连接后端WebSocket代理，而不是直接连接火山引擎
 */
import config from '@/config.js';

class StreamingTtsProxy {
  constructor() {
    this.ws = null;
    this.isConnected = false;
    this.audioContext = null;
    this.audioQueue = [];
    this.isPlaying = false;
    this.sessionId = null;
    this.listeners = new Map();
    this.userHasInteracted = false;
  }

  /**
   * 连接后端WebSocket代理
   */
  async connect() {
    return new Promise((resolve, reject) => {
      try {
        // 生成会话ID
        this.sessionId = 'tts_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        
        // 连接后端WebSocket代理
        const wsUrl = `${config.wsBaseUrl.replace('http', 'ws')}/websocket/tts/${this.sessionId}`;
        console.log('[StreamingTTS Proxy] 连接后端代理:', wsUrl);
        
        this.ws = new WebSocket(wsUrl);
        this.ws.binaryType = 'arraybuffer';

        const timeout = setTimeout(() => {
          if (!this.isConnected) {
            this.ws.close();
            reject(new Error('连接超时'));
          }
        }, 10000);

        this.ws.onopen = () => {
          clearTimeout(timeout);
          this.isConnected = true;
          console.log('[StreamingTTS Proxy] 连接已建立');
          this.emit('connected');
          resolve();
        };

        this.ws.onmessage = (event) => {
          this.handleMessage(event);
        };

        this.ws.onclose = () => {
          this.isConnected = false;
          console.log('[StreamingTTS Proxy] 连接已关闭');
          this.emit('disconnected');
        };

        this.ws.onerror = (error) => {
          clearTimeout(timeout);
          console.error('[StreamingTTS Proxy] 连接错误:', error);
          this.emit('error', error);
          reject(error);
        };

      } catch (error) {
        console.error('[StreamingTTS Proxy] 连接失败:', error);
        reject(error);
      }
    });
  }

  /**
   * 发送TTS请求
   */
  async synthesize(text, options = {}) {
    if (!this.isConnected) {
      throw new Error('WebSocket未连接');
    }

    const request = {
      type: 'synthesize',
      text: text,
      voice: options.voice || config.tts?.defaultVoice || 'zh_female_kefunvsheng_mars_bigtts',
      userId: options.userId || 'user_' + Date.now(),
      taskId: 'task_' + Date.now(),
      speedRatio: options.speedRatio || 1.0,
      volumeRatio: options.volumeRatio || 1.0,
      pitchRatio: options.pitchRatio || 1.0
    };

    console.log('[StreamingTTS Proxy] 发送TTS请求:', request);
    this.ws.send(JSON.stringify(request));
  }

  /**
   * 处理消息
   */
  handleMessage(event) {
    if (event.data instanceof ArrayBuffer) {
      // 二进制音频数据
      this.handleAudioData(event.data);
    } else {
      // 文本消息
      try {
        const message = JSON.parse(event.data);
        this.handleTextMessage(message);
      } catch (error) {
        console.error('[StreamingTTS Proxy] 解析消息失败:', error);
      }
    }
  }

  /**
   * 处理文本消息
   */
  handleTextMessage(message) {
    console.log('[StreamingTTS Proxy] 收到消息:', message);
    
    switch (message.type) {
      case 'connected':
        console.log('[StreamingTTS Proxy] 代理连接成功');
        break;
      case 'error':
        console.error('[StreamingTTS Proxy] 代理错误:', message.message);
        this.emit('error', new Error(message.message));
        break;
      case 'completed':
        console.log('[StreamingTTS Proxy] TTS合成完成');
        this.emit('completed');
        break;
      default:
        console.log('[StreamingTTS Proxy] 未知消息类型:', message.type);
    }
  }

  /**
   * 处理音频数据
   */
  handleAudioData(arrayBuffer) {
    console.log('[StreamingTTS Proxy] 收到音频数据:', {
      size: arrayBuffer.byteLength,
      type: arrayBuffer.constructor.name,
      firstBytes: Array.from(new Uint8Array(arrayBuffer.slice(0, Math.min(16, arrayBuffer.byteLength))))
    });
    
    // 检查音频数据是否有效
    if (arrayBuffer.byteLength === 0) {
      console.warn('[StreamingTTS Proxy] 收到空的音频数据，跳过');
      return;
    }
    
    // 检查是否是有效的音频格式
    const firstBytes = new Uint8Array(arrayBuffer.slice(0, 4));
    const isValidAudio = firstBytes[0] === 0xFF || // MP3帧头
                        (firstBytes[0] === 0x49 && firstBytes[1] === 0x44 && firstBytes[2] === 0x33) || // ID3标签
                        (firstBytes[0] === 0x4C && firstBytes[1] === 0x41 && firstBytes[2] === 0x4D && firstBytes[3] === 0x45); // LAME编码器标识符
    
    if (!isValidAudio) {
      console.warn('[StreamingTTS Proxy] 音频数据可能不是有效的MP3格式:', firstBytes);
    } else {
      console.log('[StreamingTTS Proxy] 音频格式验证通过:', firstBytes);
    }
    
    // 将音频数据添加到队列
    this.audioQueue.push(arrayBuffer);
    
    // 如果当前没有播放，开始播放
    if (!this.isPlaying) {
      this.playNextAudio();
    }
  }

  /**
   * 设置用户交互监听器
   */
  setupUserInteractionListener() {
    const handleUserInteraction = () => {
      if (!this.userHasInteracted) {
        this.userHasInteracted = true;
        console.log('[StreamingTTS Proxy] 检测到用户交互，激活音频权限');
      }
    };
    
    // 监听用户交互事件
    document.addEventListener('click', handleUserInteraction, { once: true });
    document.addEventListener('touchstart', handleUserInteraction, { once: true });
    document.addEventListener('keydown', handleUserInteraction, { once: true });
    
    console.log('[StreamingTTS Proxy] 用户交互监听器已设置');
  }



  /**
   * 激活音频上下文
   */
  async activateAudioContext() {
    try {
      if (!this.audioContext) {
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      }
      
      if (this.audioContext.state === 'suspended') {
        await this.audioContext.resume();
        console.log('[StreamingTTS Proxy] AudioContext已激活');
      }
    } catch (error) {
      console.warn('[StreamingTTS Proxy] AudioContext激活失败:', error);
    }
  }

  /**
   * 播放下一个音频块
   */
  async playNextAudio() {
    if (this.audioQueue.length === 0) {
      this.isPlaying = false;
      return;
    }

    this.isPlaying = true;
    const audioData = this.audioQueue.shift();

    try {
      // 创建音频上下文
      if (!this.audioContext) {
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      }

      // 如果AudioContext被暂停且无用户交互，跳过流式播放
      if (this.audioContext.state === 'suspended' && !this.userHasInteracted) {
        console.warn('[StreamingTTS Proxy] AudioContext被暂停且无用户交互，跳过流式播放');
        this.isPlaying = false;
        return;
      }

      // 检查音频数据
      if (!audioData || audioData.byteLength === 0) {
        console.warn('[StreamingTTS Proxy] 音频数据为空，跳过播放');
        this.playNextAudio();
        return;
      }

      console.log('[StreamingTTS Proxy] 尝试解码音频数据:', {
        size: audioData.byteLength,
        type: typeof audioData,
        constructor: audioData.constructor.name
      });

      // 尝试不同的解码方式
      let audioBuffer;
      try {
        // 方式1：直接解码
        audioBuffer = await this.audioContext.decodeAudioData(audioData);
      } catch (decodeError) {
        console.warn('[StreamingTTS Proxy] 直接解码失败，尝试转换为Blob:', decodeError);
        
        // 方式2：转换为Blob后解码
        const blob = new Blob([audioData], { type: 'audio/mpeg' });
        const arrayBuffer = await blob.arrayBuffer();
        audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
      }
      
      // 播放音频
      const source = this.audioContext.createBufferSource();
      source.buffer = audioBuffer;
      source.connect(this.audioContext.destination);
      
      source.onended = () => {
        // 播放完成后，播放下一个
        this.playNextAudio();
      };
      
      source.start();
      console.log('[StreamingTTS Proxy] 开始播放音频块');
      
    } catch (error) {
      console.error('[StreamingTTS Proxy] 播放音频失败:', error);
      this.isPlaying = false;
      
      // 如果是解码错误，尝试降级处理
      if (error.name === 'EncodingError') {
        console.warn('[StreamingTTS Proxy] 音频解码失败，尝试使用HTML5 Audio播放');
        this.playWithHtml5Audio(audioData);
      } else {
        this.emit('error', error);
      }
    }
  }

  /**
   * 使用HTML5 Audio播放音频（降级方案）
   */
  playWithHtml5Audio(audioData) {
    try {
      const blob = new Blob([audioData], { type: 'audio/mpeg' });
      const url = URL.createObjectURL(blob);
      const audio = new Audio(url);
      
      // 设置音频属性
      audio.preload = 'auto';
      audio.playsInline = true;
      audio.volume = 0.8;
      
      audio.onended = () => {
        URL.revokeObjectURL(url);
        console.log('[StreamingTTS Proxy] HTML5 Audio播放完成');
        this.playNextAudio();
      };
      
      audio.onerror = (error) => {
        console.error('[StreamingTTS Proxy] HTML5 Audio播放失败:', error);
        URL.revokeObjectURL(url);
        this.isPlaying = false;
        this.emit('error', error);
      };
      
      audio.onloadstart = () => {
        console.log('[StreamingTTS Proxy] HTML5 Audio开始加载');
      };
      
      audio.oncanplay = () => {
        console.log('[StreamingTTS Proxy] HTML5 Audio可以播放');
      };
      
      audio.play().then(() => {
        console.log('[StreamingTTS Proxy] HTML5 Audio播放启动成功');
      }).catch(error => {
        console.error('[StreamingTTS Proxy] HTML5 Audio播放启动失败:', error);
        URL.revokeObjectURL(url);
        this.isPlaying = false;
        this.emit('error', error);
      });
      
      console.log('[StreamingTTS Proxy] 使用HTML5 Audio播放音频，大小:', audioData.byteLength);
    } catch (error) {
      console.error('[StreamingTTS Proxy] HTML5 Audio播放失败:', error);
      this.isPlaying = false;
      this.emit('error', error);
    }
  }

  /**
   * 关闭连接
   */
  close() {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    this.isConnected = false;
    this.audioQueue = [];
    this.isPlaying = false;
  }

  /**
   * 事件监听
   */
  on(event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, []);
    }
    this.listeners.get(event).push(callback);
  }

  /**
   * 移除事件监听
   */
  off(event, callback) {
    if (this.listeners.has(event)) {
      const callbacks = this.listeners.get(event);
      const index = callbacks.indexOf(callback);
      if (index > -1) {
        callbacks.splice(index, 1);
      }
    }
  }

  /**
   * 触发事件
   */
  emit(event, ...args) {
    if (this.listeners.has(event)) {
      this.listeners.get(event).forEach(callback => {
        try {
          callback(...args);
        } catch (error) {
          console.error('[StreamingTTS Proxy] 事件回调错误:', error);
        }
      });
    }
  }
}

// 创建单例实例
const streamingTtsProxy = new StreamingTtsProxy();

export default streamingTtsProxy;
